﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using OptymalizatorTrasy.GeocodeService;
using Microsoft.Phone.Controls.Maps;
using System.Collections.ObjectModel;
using Microsoft.Phone.Controls.Maps.Platform;
using OptymalizatorTrasy.RouteService;
using System.ServiceModel;

namespace OptymalizatorTrasy
{
    public class Geokodowanie
    {
        private String ApplicationId = "ArEkpLZpUL4tqiyh7PBErNyP1NQ3XVMK1xrWSP8UsOkKyJ-2vwHEZAm60iz1bNxv"; //unikalny kod
        private GeocodeServiceClient geocodeService = null;
        private MapLayer layerP;
        private MainPage mainPage; //NOWE
        private bool czySzybka = false;

        public Geokodowanie(MapLayer layerP, MainPage mp) //NOWE
        {
            this.mainPage = mp;
            this.layerP = layerP;
            geocodeService = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
            geocodeService.GeocodeCompleted += new EventHandler<GeocodeCompletedEventArgs>(geocodeService_GeocodeCompleted);    
        }

        //funkcja zamieniająca adres w formie Stringa na pineskę i dodaje ją do mapy
        public void zamienAdresNaPinezke(String adres, bool czySzybka){
            
            GeocodeRequest geocodeRequest = new GeocodeRequest();
            geocodeRequest.Credentials = new Credentials();
            geocodeRequest.Credentials.ApplicationId = ApplicationId;
            geocodeRequest.Query = adres;

            FilterBase[] filters = new FilterBase[1];
            filters[0] = new ConfidenceFilter() { MinimumConfidence = OptymalizatorTrasy.GeocodeService.Confidence.High };

            GeocodeOptions geocodeOptions = new GeocodeOptions();
            geocodeOptions.Filters = new ObservableCollection<FilterBase>();

            foreach (var item in filters)
                geocodeOptions.Filters.Add(item);

            geocodeRequest.Options = geocodeOptions;
            geocodeService.GeocodeAsync(geocodeRequest);
            
        }
       
        private void geocodeService_GeocodeCompleted(object sender, GeocodeCompletedEventArgs e)
        {
            // The result is a GeocodeResponse object
            GeocodeResponse geocodeResponse = e.Result;

            if (geocodeResponse.Results.Count > 0)
            {                 
                    if (geocodeResponse.Results[0].Locations.Count > 0)
                    {
                        Pushpin nowyPin = new Pushpin();
                        nowyPin.Location = geocodeResponse.Results[0].Locations[0];
                        nowyPin.Content = geocodeResponse.Results[0].DisplayName;
                        layerP.Children.Add(nowyPin);
                        (App.Current as App).srodek = nowyPin.Location;
                        mainPage.mapa.Center = nowyPin.Location;

                        //jeśli jesteśmy w trybie szybkiej Trasy to wyznaczamy od razu trasę pomiędzy tymi punktami
                        if (mainPage.czySzybka)
                        {
                            RouteRequest routeRequest = new RouteRequest(); //zapytanie o długość drogi do serwera
                            routeRequest.Credentials = new Credentials();
                            routeRequest.Credentials.ApplicationId = ApplicationId;
                            routeRequest.Waypoints = new ObservableCollection<Waypoint>(); //stworzenie kolekcji punktów będącymi lokalizacjami

                            Waypoint p1 = new Waypoint();
                            p1.Location = mainPage.pinPozycja.Location;
                            routeRequest.Waypoints.Add(p1);

                            Waypoint p2 = new Waypoint();
                            p2.Location = nowyPin.Location;
                            routeRequest.Waypoints.Add(p2);

                            //ustawienie opcji zapytania do serwera
                            routeRequest.Options = new RouteOptions();
                            routeRequest.Options.RoutePathType = RoutePathType.Points;
                            routeRequest.UserProfile = new OptymalizatorTrasy.RouteService.UserProfile();
                            routeRequest.UserProfile.DistanceUnit = OptymalizatorTrasy.RouteService.DistanceUnit.Kilometer;

                            //wykonanie zapytania do serwera  
                            RouteServiceClient routeClient = new RouteServiceClient("BasicHttpBinding_IRouteService");
                            routeClient.CalculateRouteCompleted += new EventHandler<CalculateRouteCompletedEventArgs>(routeService_CalculateRouteCompleted);
                           routeClient.CalculateRouteAsync(routeRequest); 

                    }
            }

           
            }

        

        }


        void routeService_CalculateRouteCompleted(object sender, CalculateRouteCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (e.Error is FaultException)
                {
                    MessageBox.Show("Nie można wyznaczyć trasy - brak dojazdu do wyznaczenoge punktu");
                }
                else
                {
                    MessageBox.Show("Error: " + e.Error.ToString());
                }
            }
            else
            {

                if (e.Result != null)
                {

                    MapPolyline routeLine = new MapPolyline(); //stworzenie MapPolyLine i ustawienie jego parametrów
                    routeLine.Locations = new LocationCollection();
                    routeLine.Stroke = new SolidColorBrush(Colors.Blue);
                    routeLine.Opacity = 0.50;
                    routeLine.StrokeThickness = 5.0;

                    foreach (Location p in e.Result.Result.RoutePath.Points)
                    {
                        routeLine.Locations.Add(new Location { Latitude = p.Latitude, Longitude = p.Longitude });
                    }

                    mainPage.layerT.Children.Add(routeLine);

                    mainPage.dlugoscTrasy.Text = "Długość trasy: " + Convert.ToString(e.Result.Result.Summary.Distance);
                    mainPage.dlugoscTrasy.Visibility = Visibility.Visible;

                }
            }
        }
    }
}
